// 
// Bachelor of Software Engineering
// Media Design School
// Auckland
// New Zealand
//
// (c) 2005 - 2014 Media Design School
//
// File Name	: BuildStack.cpp
// Desrciption	: CBuildStack implementation file.
// Author(s)	: Hayden Asplet.
// Mail			: hayden.asplet@mediadesignschool.com
//

// PCH
#include "SolitaireStd.h"

// Library Includes

// This Include
#include "BuildStack.h"

// Local Includes


CBuildStack::CBuildStack()
	:CCardStack()
{
}

CBuildStack::CBuildStack(const CPoint& _krPosition, int _iOffset, const EStackDirection& _krDirection)
	:CCardStack(_krPosition, _iOffset, _krDirection)
{

}


CBuildStack::CBuildStack(const CBuildStack& _krStack)
	:CCardStack(_krStack)
{

}

CBuildStack::~CBuildStack()
{
}

bool CBuildStack::CanBePushed(const CPlayingCard& _krCard)
{
	if(IsEmpty() && m_lerpingCards.empty()) {
		if(_krCard.GetValue() == keKing) {
			return true;
		}
		else {
			return false;
		}
	}

	CPlayingCard topCard;

	if(!m_lerpingCards.empty()) {
		topCard = m_lerpingCards.back();
	}
	else {
		topCard = Peek();
	}

	if(topCard.IsFaceDown()) {
		return false;
	}
	else if(_krCard.GetValue() == topCard.GetValue() - 1) {
		if(topCard.IsRed() && _krCard.IsBlack()) {
		// Different colours.
			return true;
		}
		else if(topCard.IsBlack() && _krCard.IsRed()) {
		// Different colours.
			return true;
		}
		else {
		// Same colours.
			return false;
		}
	}

	return false;
}

bool CBuildStack::CanBePushed(const TStack& _krStack)
{
	if(_krStack.empty()) {
		return false;
	}

	CPlayingCard bottomCard = _krStack[0];

	if(IsEmpty() && m_lerpingCards.empty()) {
		if(bottomCard.GetValue() == keKing) {
			return true;
		}
		else {
			return false;
		}
	}

	CPlayingCard topCard;

	if(!m_lerpingCards.empty()) {
		topCard = m_lerpingCards.back();
	}
	else {
		topCard = Peek();
	}

	if(topCard.IsFaceDown()) {
		return false;
	}
	else if(bottomCard.GetValue() == topCard.GetValue() - 1) {
		if(topCard.IsRed() && bottomCard.IsBlack()) {
		// Different colours.
			return true;
		}
		else if(topCard.IsBlack() && bottomCard.IsRed()) {
		// Different colours.
			return true;
		}
		else {
		// Same colours.
			return false;
		}
	}

	return false;
}

CPoint CBuildStack::VGetNextPosition() const
{
	int iHalfOffset = static_cast<int>(m_iOffset / 2.0f);

	CPoint currentPosition(m_position);

	for(int i = 0; i <= Size(); ++i) {
		if(i == 0) {
		}
		else if(m_eDirection == keDown) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition += CPoint(0, iHalfOffset);
			}
			else {
				currentPosition += CPoint(0, m_iOffset);
			}
		}
		else if(m_eDirection == keRight) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition +=  CPoint(iHalfOffset, 0);
			}
			else {
				currentPosition +=  CPoint(m_iOffset, 0);
			}
		}
		else if(m_eDirection == keBoth) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition = currentPosition + CPoint(iHalfOffset, iHalfOffset);
			}
			else {
				currentPosition = currentPosition + CPoint(m_iOffset, m_iOffset);
			}
		}
	}

	std::list<CPlayingCard>::const_iterator iter = m_lerpingCards.begin();
	std::list<CPlayingCard>::const_iterator prevIter = iter;

	while(prevIter != m_lerpingCards.end()) {	// We need to go one beyond the end.
		if(iter == m_lerpingCards.begin()) {
		}
		else if(m_eDirection == keDown) {
			if((*prevIter).IsFaceDown()) {
			// The previous card was face down.
				currentPosition += CPoint(0, iHalfOffset);
			}
			else {
				currentPosition += CPoint(0, m_iOffset);
			}
		}
		else if(m_eDirection == keRight) {
			if((*prevIter).IsFaceDown()) {
			// The previous card was face down.
				currentPosition +=  CPoint(iHalfOffset, 0);
			}
			else {
				currentPosition +=  CPoint(m_iOffset, 0);
			}
		}
		else if(m_eDirection == keBoth) {
			if((*prevIter).IsFaceDown()) {
			// The previous card was face down.
				currentPosition = currentPosition + CPoint(iHalfOffset, iHalfOffset);
			}
			else {
				currentPosition = currentPosition + CPoint(m_iOffset, m_iOffset);
			}
		}

		prevIter = iter;

		if(iter != m_lerpingCards.end()) {
		// Make sure we don't increment past the end.
			++iter;
		}
	}

	return currentPosition;
}

void CBuildStack::VUpdatePositions()
{
	int iHalfOffset = static_cast<int>(m_iOffset / 2.0f);

	CPoint currentPosition(m_position);

	for(int i = 0; i < Size(); ++i) {
		if(i == 0) {
			m_cards[i].SetPosition(currentPosition);
		}
		else if(m_eDirection == keDown) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition += CPoint(0, iHalfOffset);
			}
			else {
				currentPosition += CPoint(0, m_iOffset);
			}
		}
		else if(m_eDirection == keRight) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition +=  CPoint(iHalfOffset, 0);
			}
			else {
				currentPosition +=  CPoint(m_iOffset, 0);
			}
		}
		else if(m_eDirection == keBoth) {
			if(m_cards[i - 1].IsFaceDown()) {
			// The previous card was face down.
				currentPosition = currentPosition + CPoint(iHalfOffset, iHalfOffset);
			}
			else {
				currentPosition = currentPosition + CPoint(m_iOffset, m_iOffset);
			}
		}

		m_cards[i].SetPosition(currentPosition);
	}
}